# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: textwrap.py
"""Text wrapping and filling.
"""
import re
__all__ = [
 'TextWrapper', 'wrap', 'fill', 'dedent', 'indent', 'shorten']
_whitespace = '\t\n\x0b\x0c\r '

class TextWrapper:
    """
    Object for wrapping/filling text.  The public interface consists of
    the wrap() and fill() methods; the other methods are just there for
    subclasses to override in order to tweak the default behaviour.
    If you want to completely replace the main wrapping algorithm,
    you'll probably have to override _wrap_chunks().
    
    Several instance attributes control various aspects of wrapping:
      width (default: 70)
        the maximum width of wrapped lines (unless break_long_words
        is false)
      initial_indent (default: "")
        string that will be prepended to the first line of wrapped
        output.  Counts towards the line's width.
      subsequent_indent (default: "")
        string that will be prepended to all lines save the first
        of wrapped output; also counts towards each line's width.
      expand_tabs (default: true)
        Expand tabs in input text to spaces before further processing.
        Each tab will become 0 .. 'tabsize' spaces, depending on its position
        in its line.  If false, each tab is treated as a single character.
      tabsize (default: 8)
        Expand tabs in input text to 0 .. 'tabsize' spaces, unless
        'expand_tabs' is false.
      replace_whitespace (default: true)
        Replace all whitespace characters in the input text by spaces
        after tab expansion.  Note that if expand_tabs is false and
        replace_whitespace is true, every tab will be converted to a
        single space!
      fix_sentence_endings (default: false)
        Ensure that sentence-ending punctuation is always followed
        by two spaces.  Off by default because the algorithm is
        (unavoidably) imperfect.
      break_long_words (default: true)
        Break words longer than 'width'.  If false, those words will not
        be broken, and some lines might be longer than 'width'.
      break_on_hyphens (default: true)
        Allow breaking hyphenated words. If true, wrapping will occur
        preferably on whitespaces and right after hyphens part of
        compound words.
      drop_whitespace (default: true)
        Drop leading and trailing whitespace from lines.
      max_lines (default: None)
        Truncate wrapped lines.
      placeholder (default: ' [...]')
        Append to the last line of truncated text.
    """
    unicode_whitespace_trans = {}
    uspace = ord(' ')
    for x in _whitespace:
        unicode_whitespace_trans[ord(x)] = uspace

    word_punct = '[\\w!"\\\'&.,?]'
    letter = '[^\\d\\W]'
    whitespace = '[%s]' % re.escape(_whitespace)
    nowhitespace = '[^' + whitespace[1:]
    wordsep_re = re.compile('\n        ( # any whitespace\n          %(ws)s+\n        | # em-dash between words\n          (?<=%(wp)s) -{2,} (?=\\w)\n        | # word, possibly hyphenated\n          %(nws)s+? (?:\n            # hyphenated word\n              -(?: (?<=%(lt)s{2}-) | (?<=%(lt)s-%(lt)s-))\n              (?= %(lt)s -? %(lt)s)\n            | # end of word\n              (?=%(ws)s|\\Z)\n            | # em-dash\n              (?<=%(wp)s) (?=-{2,}\\w)\n            )\n        )' % {'wp':word_punct,  'lt':letter,  'ws':whitespace, 
     'nws':nowhitespace}, re.VERBOSE)
    del word_punct
    del letter
    del nowhitespace
    wordsep_simple_re = re.compile('(%s+)' % whitespace)
    del whitespace
    sentence_end_re = re.compile('[a-z][\\.\\!\\?][\\"\\\']?\\Z')

    def __init__(self, width=70, initial_indent='', subsequent_indent='', expand_tabs=True, replace_whitespace=True, fix_sentence_endings=False, break_long_words=True, drop_whitespace=True, break_on_hyphens=True, tabsize=8, *, max_lines=None, placeholder=' [...]'):
        self.width = width
        self.initial_indent = initial_indent
        self.subsequent_indent = subsequent_indent
        self.expand_tabs = expand_tabs
        self.replace_whitespace = replace_whitespace
        self.fix_sentence_endings = fix_sentence_endings
        self.break_long_words = break_long_words
        self.drop_whitespace = drop_whitespace
        self.break_on_hyphens = break_on_hyphens
        self.tabsize = tabsize
        self.max_lines = max_lines
        self.placeholder = placeholder

    def _munge_whitespace(self, text):
        r"""_munge_whitespace(text : string) -> string
        
        Munge whitespace in text: expand tabs and convert all other
        whitespace characters to spaces.  Eg. " foo\tbar\n\nbaz"
        becomes " foo    bar  baz".
        """
        if self.expand_tabs:
            text = text.expandtabs(self.tabsize)
        if self.replace_whitespace:
            text = text.translate(self.unicode_whitespace_trans)
        return text

    def _split(self, text):
        """_split(text : string) -> [string]
        
        Split the text to wrap into indivisible chunks.  Chunks are
        not quite the same as words; see _wrap_chunks() for full
        details.  As an example, the text
          Look, goof-ball -- use the -b option!
        breaks into the following chunks:
          'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
          'use', ' ', 'the', ' ', '-b', ' ', 'option!'
        if break_on_hyphens is True, or in:
          'Look,', ' ', 'goof-ball', ' ', '--', ' ',
          'use', ' ', 'the', ' ', '-b', ' ', option!'
        otherwise.
        """
        if self.break_on_hyphens is True:
            chunks = self.wordsep_re.split(text)
        else:
            chunks = self.wordsep_simple_re.split(text)
        chunks = [c for c in chunks if c]
        return chunks

    def _fix_sentence_endings(self, chunks):
        r"""_fix_sentence_endings(chunks : [string])
        
        Correct for sentence endings buried in 'chunks'.  Eg. when the
        original text contains "... foo.\nBar ...", munge_whitespace()
        and split() will convert that to [..., "foo.", " ", "Bar", ...]
        which has one too few spaces; this method simply changes the one
        space to two.
        """
        i = 0
        patsearch = self.sentence_end_re.search
        while i < len(chunks) - 1:
            if chunks[i + 1] == ' ':
                if patsearch(chunks[i]):
                    chunks[i + 1] = '  '
                    i += 2
            else:
                i += 1

    def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
        """_handle_long_word(chunks : [string],
                             cur_line : [string],
                             cur_len : int, width : int)
        
        Handle a chunk of text (most likely a word, not whitespace) that
        is too long to fit in any line.
        """
        if width < 1:
            space_left = 1
        else:
            space_left = width - cur_len
        if self.break_long_words:
            cur_line.append(reversed_chunks[-1][:space_left])
            reversed_chunks[-1] = reversed_chunks[-1][space_left:]
        else:
            if not cur_line:
                cur_line.append(reversed_chunks.pop())

    def _wrap_chunks--- This code section failed: ---

 246       0  BUILD_LIST_0          0  ''
           2  STORE_FAST               'lines'

 247       4  LOAD_FAST                'self'
           6  LOAD_ATTR                'width'
           8  LOAD_CONST            0  0
          10  COMPARE_OP               '<='
          12  POP_JUMP_IF_FALSE    28  'to 28'

 248      14  LOAD_GLOBAL              'ValueError'
          16  LOAD_CONST               'invalid width %r (must be > 0)'
          18  LOAD_FAST                'self'
          20  LOAD_ATTR                'width'
          22  BINARY_MODULO    
          24  CALL_FUNCTION_1       1  ''
          26  RAISE_VARARGS_1       1  ''
        28_0  COME_FROM            12  '12'

 249      28  LOAD_FAST                'self'
          30  LOAD_ATTR                'max_lines'
          32  LOAD_CONST               None
          34  COMPARE_OP               'is-not'
          36  POP_JUMP_IF_FALSE    98  'to 98'

 250      38  LOAD_FAST                'self'
          40  LOAD_ATTR                'max_lines'
          42  LOAD_CONST            1  1
          44  COMPARE_OP               '>'
          46  POP_JUMP_IF_FALSE    56  'to 56'

 251      48  LOAD_FAST                'self'
          50  LOAD_ATTR                'subsequent_indent'
          52  STORE_FAST               'indent'
          54  JUMP_FORWARD         62  'to 62'
          56  ELSE                     '62'

 253      56  LOAD_FAST                'self'
          58  LOAD_ATTR                'initial_indent'
          60  STORE_FAST               'indent'
        62_0  COME_FROM            54  '54'

 254      62  LOAD_GLOBAL              'len'
          64  LOAD_FAST                'indent'
          66  CALL_FUNCTION_1       1  ''
          68  LOAD_GLOBAL              'len'
          70  LOAD_FAST                'self'
          72  LOAD_ATTR                'placeholder'
          74  LOAD_ATTR                'lstrip'
          76  CALL_FUNCTION_0       0  ''
          78  CALL_FUNCTION_1       1  ''
          80  BINARY_ADD       
          82  LOAD_FAST                'self'
          84  LOAD_ATTR                'width'
          86  COMPARE_OP               '>'
          88  POP_JUMP_IF_FALSE    98  'to 98'

 255      90  LOAD_GLOBAL              'ValueError'
          92  LOAD_CONST               'placeholder too large for max width'
          94  CALL_FUNCTION_1       1  ''
          96  RAISE_VARARGS_1       1  ''
        98_0  COME_FROM            88  '88'
        98_1  COME_FROM            36  '36'

 259      98  LOAD_FAST                'chunks'
         100  LOAD_ATTR                'reverse'
         102  CALL_FUNCTION_0       0  ''
         104  POP_TOP          

 261     106  SETUP_LOOP          660  'to 660'
         110  LOAD_FAST                'chunks'
         112  POP_JUMP_IF_FALSE   658  'to 658'

 265     116  BUILD_LIST_0          0  ''
         118  STORE_FAST               'cur_line'

 266     120  LOAD_CONST            0  0
         122  STORE_FAST               'cur_len'

 269     124  LOAD_FAST                'lines'
         126  POP_JUMP_IF_FALSE   136  'to 136'

 270     128  LOAD_FAST                'self'
         130  LOAD_ATTR                'subsequent_indent'
         132  STORE_FAST               'indent'
         134  JUMP_FORWARD        142  'to 142'
         136  ELSE                     '142'

 272     136  LOAD_FAST                'self'
         138  LOAD_ATTR                'initial_indent'
         140  STORE_FAST               'indent'
       142_0  COME_FROM           134  '134'

 275     142  LOAD_FAST                'self'
         144  LOAD_ATTR                'width'
         146  LOAD_GLOBAL              'len'
         148  LOAD_FAST                'indent'
         150  CALL_FUNCTION_1       1  ''
         152  BINARY_SUBTRACT  
         154  STORE_FAST               'width'

 279     156  LOAD_FAST                'self'
         158  LOAD_ATTR                'drop_whitespace'
         160  POP_JUMP_IF_FALSE   188  'to 188'
         162  LOAD_FAST                'chunks'
         164  LOAD_CONST           -1  -1
         166  BINARY_SUBSCR    
         168  LOAD_ATTR                'strip'
         170  CALL_FUNCTION_0       0  ''
         172  LOAD_CONST               ''
         174  COMPARE_OP               '=='
         176  POP_JUMP_IF_FALSE   188  'to 188'
         178  LOAD_FAST                'lines'
         180  POP_JUMP_IF_FALSE   188  'to 188'

 280     182  LOAD_FAST                'chunks'
         184  LOAD_CONST           -1  -1
         186  DELETE_SUBSCR    
       188_0  COME_FROM           180  '180'
       188_1  COME_FROM           176  '176'
       188_2  COME_FROM           160  '160'

 282     188  SETUP_LOOP          248  'to 248'
         190  LOAD_FAST                'chunks'
         192  POP_JUMP_IF_FALSE   246  'to 246'

 283     194  LOAD_GLOBAL              'len'
         196  LOAD_FAST                'chunks'
         198  LOAD_CONST           -1  -1
         200  BINARY_SUBSCR    
         202  CALL_FUNCTION_1       1  ''
         204  STORE_FAST               'l'

 286     206  LOAD_FAST                'cur_len'
         208  LOAD_FAST                'l'
         210  BINARY_ADD       
         212  LOAD_FAST                'width'
         214  COMPARE_OP               '<='
         216  POP_JUMP_IF_FALSE   242  'to 242'

 287     218  LOAD_FAST                'cur_line'
         220  LOAD_ATTR                'append'
         222  LOAD_FAST                'chunks'
         224  LOAD_ATTR                'pop'
         226  CALL_FUNCTION_0       0  ''
         228  CALL_FUNCTION_1       1  ''
         230  POP_TOP          

 288     232  LOAD_FAST                'cur_len'
         234  LOAD_FAST                'l'
         236  INPLACE_ADD      
         238  STORE_FAST               'cur_len'
         240  JUMP_BACK           190  'to 190'
         242  ELSE                     '244'

 292     242  BREAK_LOOP       
         244  JUMP_BACK           190  'to 190'
         246  POP_BLOCK        
       248_0  COME_FROM_LOOP      188  '188'

 296     248  LOAD_FAST                'chunks'
         250  POP_JUMP_IF_FALSE   302  'to 302'
         254  LOAD_GLOBAL              'len'
         256  LOAD_FAST                'chunks'
         258  LOAD_CONST           -1  -1
         260  BINARY_SUBSCR    
         262  CALL_FUNCTION_1       1  ''
         264  LOAD_FAST                'width'
         266  COMPARE_OP               '>'
         268  POP_JUMP_IF_FALSE   302  'to 302'

 297     272  LOAD_FAST                'self'
         274  LOAD_ATTR                '_handle_long_word'
         276  LOAD_FAST                'chunks'
         278  LOAD_FAST                'cur_line'
         280  LOAD_FAST                'cur_len'
         282  LOAD_FAST                'width'
         284  CALL_FUNCTION_4       4  ''
         286  POP_TOP          

 298     288  LOAD_GLOBAL              'sum'
         290  LOAD_GLOBAL              'map'
         292  LOAD_GLOBAL              'len'
         294  LOAD_FAST                'cur_line'
         296  CALL_FUNCTION_2       2  ''
         298  CALL_FUNCTION_1       1  ''
         300  STORE_FAST               'cur_len'
       302_0  COME_FROM           268  '268'
       302_1  COME_FROM           250  '250'

 301     302  LOAD_FAST                'self'
         304  LOAD_ATTR                'drop_whitespace'
         306  POP_JUMP_IF_FALSE   356  'to 356'
         310  LOAD_FAST                'cur_line'
         312  POP_JUMP_IF_FALSE   356  'to 356'
         316  LOAD_FAST                'cur_line'
         318  LOAD_CONST           -1  -1
         320  BINARY_SUBSCR    
         322  LOAD_ATTR                'strip'
         324  CALL_FUNCTION_0       0  ''
         326  LOAD_CONST               ''
         328  COMPARE_OP               '=='
         330  POP_JUMP_IF_FALSE   356  'to 356'

 302     334  LOAD_FAST                'cur_len'
         336  LOAD_GLOBAL              'len'
         338  LOAD_FAST                'cur_line'
         340  LOAD_CONST           -1  -1
         342  BINARY_SUBSCR    
         344  CALL_FUNCTION_1       1  ''
         346  INPLACE_SUBTRACT 
         348  STORE_FAST               'cur_len'

 303     350  LOAD_FAST                'cur_line'
         352  LOAD_CONST           -1  -1
         354  DELETE_SUBSCR    
       356_0  COME_FROM           330  '330'
       356_1  COME_FROM           312  '312'
       356_2  COME_FROM           306  '306'

 305     356  LOAD_FAST                'cur_line'
         358  POP_JUMP_IF_FALSE   110  'to 110'

 306     360  LOAD_FAST                'self'
         362  LOAD_ATTR                'max_lines'
         364  LOAD_CONST               None
         366  COMPARE_OP               'is'
         368  POP_JUMP_IF_TRUE    448  'to 448'

 307     372  LOAD_GLOBAL              'len'
         374  LOAD_FAST                'lines'
         376  CALL_FUNCTION_1       1  ''
         378  LOAD_CONST            1  1
         380  BINARY_ADD       
         382  LOAD_FAST                'self'
         384  LOAD_ATTR                'max_lines'
         386  COMPARE_OP               '<'
         388  POP_JUMP_IF_TRUE    448  'to 448'

 308     392  LOAD_FAST                'chunks'
         394  UNARY_NOT        
         396  POP_JUMP_IF_TRUE    438  'to 438'

 309     400  LOAD_FAST                'self'
         402  LOAD_ATTR                'drop_whitespace'
         404  POP_JUMP_IF_FALSE   470  'to 470'

 310     408  LOAD_GLOBAL              'len'
         410  LOAD_FAST                'chunks'
         412  CALL_FUNCTION_1       1  ''
         414  LOAD_CONST            1  1
         416  COMPARE_OP               '=='
         418  POP_JUMP_IF_FALSE   470  'to 470'

 311     422  LOAD_FAST                'chunks'
         424  LOAD_CONST            0  0
         426  BINARY_SUBSCR    
         428  LOAD_ATTR                'strip'
         430  CALL_FUNCTION_0       0  ''
         432  UNARY_NOT        
       434_0  COME_FROM           418  '418'
       434_1  COME_FROM           404  '404'
       434_2  COME_FROM           396  '396'
         434  POP_JUMP_IF_FALSE   470  'to 470'
         438  LOAD_FAST                'cur_len'
         440  LOAD_FAST                'width'
         442  COMPARE_OP               '<='
       444_0  COME_FROM           434  '434'
       444_1  COME_FROM           388  '388'
       444_2  COME_FROM           368  '368'
         444  POP_JUMP_IF_FALSE   470  'to 470'

 314     448  LOAD_FAST                'lines'
         450  LOAD_ATTR                'append'
         452  LOAD_FAST                'indent'
         454  LOAD_CONST               ''
         456  LOAD_ATTR                'join'
         458  LOAD_FAST                'cur_line'
         460  CALL_FUNCTION_1       1  ''
         462  BINARY_ADD       
         464  CALL_FUNCTION_1       1  ''
         466  POP_TOP          
         468  JUMP_BACK           110  'to 110'
         470  ELSE                     '656'

 316     470  SETUP_LOOP          654  'to 654'
         472  LOAD_FAST                'cur_line'
         474  POP_JUMP_IF_FALSE   572  'to 572'

 317     478  LOAD_FAST                'cur_line'
         480  LOAD_CONST           -1  -1
         482  BINARY_SUBSCR    
         484  LOAD_ATTR                'strip'
         486  CALL_FUNCTION_0       0  ''
         488  POP_JUMP_IF_FALSE   546  'to 546'

 318     492  LOAD_FAST                'cur_len'
         494  LOAD_GLOBAL              'len'
         496  LOAD_FAST                'self'
         498  LOAD_ATTR                'placeholder'
         500  CALL_FUNCTION_1       1  ''
         502  BINARY_ADD       
         504  LOAD_FAST                'width'
         506  COMPARE_OP               '<='
         508  POP_JUMP_IF_FALSE   546  'to 546'

 319     512  LOAD_FAST                'cur_line'
         514  LOAD_ATTR                'append'
         516  LOAD_FAST                'self'
         518  LOAD_ATTR                'placeholder'
         520  CALL_FUNCTION_1       1  ''
         522  POP_TOP          

 320     524  LOAD_FAST                'lines'
         526  LOAD_ATTR                'append'
         528  LOAD_FAST                'indent'
         530  LOAD_CONST               ''
         532  LOAD_ATTR                'join'
         534  LOAD_FAST                'cur_line'
         536  CALL_FUNCTION_1       1  ''
         538  BINARY_ADD       
         540  CALL_FUNCTION_1       1  ''
         542  POP_TOP          

 321     544  BREAK_LOOP       
       546_0  COME_FROM           508  '508'
       546_1  COME_FROM           488  '488'

 322     546  LOAD_FAST                'cur_len'
         548  LOAD_GLOBAL              'len'
         550  LOAD_FAST                'cur_line'
         552  LOAD_CONST           -1  -1
         554  BINARY_SUBSCR    
         556  CALL_FUNCTION_1       1  ''
         558  INPLACE_SUBTRACT 
         560  STORE_FAST               'cur_len'

 323     562  LOAD_FAST                'cur_line'
         564  LOAD_CONST           -1  -1
         566  DELETE_SUBSCR    
         568  JUMP_BACK           472  'to 472'
       572_0  COME_FROM           474  '474'
         572  POP_BLOCK        

 325     574  LOAD_FAST                'lines'
         576  POP_JUMP_IF_FALSE   634  'to 634'

 326     580  LOAD_FAST                'lines'
         582  LOAD_CONST           -1  -1
         584  BINARY_SUBSCR    
         586  LOAD_ATTR                'rstrip'
         588  CALL_FUNCTION_0       0  ''
         590  STORE_FAST               'prev_line'

 327     592  LOAD_GLOBAL              'len'
         594  LOAD_FAST                'prev_line'
         596  CALL_FUNCTION_1       1  ''
         598  LOAD_GLOBAL              'len'
         600  LOAD_FAST                'self'
         602  LOAD_ATTR                'placeholder'
         604  CALL_FUNCTION_1       1  ''
         606  BINARY_ADD       

 328     608  LOAD_FAST                'self'
         610  LOAD_ATTR                'width'
         612  COMPARE_OP               '<='
         614  POP_JUMP_IF_FALSE   634  'to 634'

 329     618  LOAD_FAST                'prev_line'
         620  LOAD_FAST                'self'
         622  LOAD_ATTR                'placeholder'
         624  BINARY_ADD       
         626  LOAD_FAST                'lines'
         628  LOAD_CONST           -1  -1
         630  STORE_SUBSCR     

 330     632  BREAK_LOOP       
       634_0  COME_FROM           614  '614'
       634_1  COME_FROM           576  '576'

 331     634  LOAD_FAST                'lines'
         636  LOAD_ATTR                'append'
         638  LOAD_FAST                'indent'
         640  LOAD_FAST                'self'
         642  LOAD_ATTR                'placeholder'
         644  LOAD_ATTR                'lstrip'
         646  CALL_FUNCTION_0       0  ''
         648  BINARY_ADD       
         650  CALL_FUNCTION_1       1  ''
         652  POP_TOP          
       654_0  COME_FROM_LOOP      470  '470'

 332     654  BREAK_LOOP       
       656_0  COME_FROM           358  '358'
       656_1  COME_FROM           112  '112'
         656  JUMP_BACK           110  'to 110'
         658  POP_BLOCK        
       660_0  COME_FROM_LOOP      106  '106'

 334     660  LOAD_FAST                'lines'
         662  RETURN_VALUE     
          -1  RETURN_LAST      

Parse error at or near `LOAD_FAST' instruction at offset 574

    def _split_chunks(self, text):
        text = self._munge_whitespace(text)
        return self._split(text)

    def wrap(self, text):
        """wrap(text : string) -> [string]
        
        Reformat the single paragraph in 'text' so it fits in lines of
        no more than 'self.width' columns, and return a list of wrapped
        lines.  Tabs in 'text' are expanded with string.expandtabs(),
        and all other whitespace characters (including newline) are
        converted to space.
        """
        chunks = self._split_chunks(text)
        if self.fix_sentence_endings:
            self._fix_sentence_endings(chunks)
        return self._wrap_chunks(chunks)

    def fill(self, text):
        """fill(text : string) -> string
        
        Reformat the single paragraph in 'text' to fit in lines of no
        more than 'self.width' columns, and return a new string
        containing the entire wrapped paragraph.
        """
        return ('\n').join(self.wrap(text))


def wrap(text, width=70, **kwargs):
    """Wrap a single paragraph of text, returning a list of wrapped lines.
    
    Reformat the single paragraph in 'text' so it fits in lines of no
    more than 'width' columns, and return a list of wrapped lines.  By
    default, tabs in 'text' are expanded with string.expandtabs(), and
    all other whitespace characters (including newline) are converted to
    space.  See TextWrapper class for available keyword args to customize
    wrapping behaviour.
    """
    w = TextWrapper(width=width, **kwargs)
    return w.wrap(text)


def fill(text, width=70, **kwargs):
    """Fill a single paragraph of text, returning a new string.
    
    Reformat the single paragraph in 'text' to fit in lines of no more
    than 'width' columns, and return a new string containing the entire
    wrapped paragraph.  As with wrap(), tabs are expanded and other
    whitespace characters converted to space.  See TextWrapper class for
    available keyword args to customize wrapping behaviour.
    """
    w = TextWrapper(width=width, **kwargs)
    return w.fill(text)


def shorten(text, width, **kwargs):
    """Collapse and truncate the given text to fit in the given width.
    
    The text first has its whitespace collapsed.  If it then fits in
    the *width*, it is returned as is.  Otherwise, as many words
    as possible are joined and then the placeholder is appended::
    
        >>> textwrap.shorten("Hello  world!", width=12)
        'Hello world!'
        >>> textwrap.shorten("Hello  world!", width=11)
        'Hello [...]'
    """
    w = TextWrapper(width=width, max_lines=1, **kwargs)
    return w.fill((' ').join(text.strip().split()))


_whitespace_only_re = re.compile('^[ \t]+$', re.MULTILINE)
_leading_whitespace_re = re.compile('(^[ \t]*)(?:[^ \t\n])', re.MULTILINE)

def dedent(text):
    r"""Remove any common leading whitespace from every line in `text`.
    
    This can be used to make triple-quoted strings line up with the left
    edge of the display, while still presenting them in the source code
    in indented form.
    
    Note that tabs and spaces are both treated as whitespace, but they
    are not equal: the lines "  hello" and "\thello" are
    considered to have no common leading whitespace.  (This behaviour is
    new in Python 2.5; older versions of this module incorrectly
    expanded tabs before searching for common leading whitespace.)
    """
    margin = None
    text = _whitespace_only_re.sub('', text)
    indents = _leading_whitespace_re.findall(text)
    for indent in indents:
        if margin is None:
            margin = indent
        else:
            if indent.startswith(margin):
                continue
            if margin.startswith(indent):
                margin = indent
            else:
                for i, (x, y) in enumerate(zip(margin, indent)):
                    if x != y:
                        margin = margin[:i]
                        break
                else:
                    margin = margin[:len(indent)]

    if 0:
        if margin:
            for line in text.split('\n'):
                if not not line:
                    if not line.startswith(margin):
                        raise AssertionError('line = %r, margin = %r' % (line, margin))

    if margin:
        text = re.sub('(?m)^' + margin, '', text)
    return text


def indent(text, prefix, predicate=None):
    """Adds 'prefix' to the beginning of selected lines in 'text'.
    
    If 'predicate' is provided, 'prefix' will only be added to the lines
    where 'predicate(line)' is True. If 'predicate' is not provided,
    it will default to adding 'prefix' to all non-empty lines that do not
    consist solely of whitespace characters.
    """
    if predicate is None:

        def predicate(line):
            return line.strip()

    def prefixed_lines():
        for line in text.splitlines(True):
            yield prefix + line if predicate(line) else line

    return ('').join(prefixed_lines())


if __name__ == '__main__':
    print(dedent('Hello there.\n  This is indented.'))